package cn.org.seventh.web.common;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.org.seventh.common.LocaleUtil;

/**
 * @author <a href="mailto:young@hrzsoft.cn">Zhou Yang</a>
 * @version $Id: LocaleFilter.java 499 2007-08-03 07:44:43Z young $
 */
public class LocaleFilter implements Filter {
	private transient Log log = LogFactory.getLog(LocaleFilter.class);

	private static final String SPECIFIED_LOCALE = "specifiedLocale";

	private static final String LOCALE = "locale";

	private static final String ENCODING = "encoding";

	private String localeConfig;

	private String encodingConfig;

	public void doFilter(ServletRequest servletRequest,
			ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;

		Cookie[] cookies = request.getCookies();
		Cookie langCookie = null;
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				if ("siteLanguage".equals(cookies[i].getName())) {
					langCookie = cookies[i];
					break;
				}
			}
		}
		Locale locale = (Locale) request.getSession().getAttribute(
				SPECIFIED_LOCALE);

		String lang;
		if (langCookie == null) {
			if (locale == null) {
				lang = (String) request.getSession().getAttribute(LOCALE);
				locale = LocaleUtil.getLocale(lang, localeConfig);

				request.getSession().setAttribute(LOCALE, locale.toString());
				request.getSession().setAttribute(SPECIFIED_LOCALE, locale);
			}
		} else if (locale == null
				|| !locale.toString().equals(langCookie.getValue())) {
			locale = LocaleUtil.getLocale(langCookie.getValue());
			request.getSession().setAttribute(SPECIFIED_LOCALE, locale);
			request.getSession().setAttribute(LOCALE, locale.toString());
		}
		HttpServletRequestWrapper localeRequest = new LocaleRequestWrapper(
				request, locale);
		localeRequest.setCharacterEncoding(encodingConfig);

		((HttpServletResponse) servletResponse)
				.setCharacterEncoding(encodingConfig);

		filterChain.doFilter(localeRequest, servletResponse);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		localeConfig = filterConfig.getServletContext()
				.getInitParameter(LOCALE);
		if (localeConfig == null) {
			localeConfig = filterConfig.getInitParameter(LOCALE);
		}
		encodingConfig = filterConfig.getServletContext().getInitParameter(
				ENCODING);
		if (encodingConfig == null) {
			encodingConfig = filterConfig.getInitParameter(ENCODING);
		}
	}

	public void destroy() {
	}
}
